Leaning Weekly-2025-02-09
Chain-call delayed executor
ts
/**
* 一个可以链式调用并添加延迟执行的方法
* @author: Ruan Jiazhen
* @date: 2025-02-04 18:11:14
**/
/**
* 一个可以链式调用并添加延迟执行的执行器
*/
interface ChainCallDelayedExecutor {
/**
* 添加一个任务到任务队列中
* @param callback 任务函数
*/
do: (callback: Function) => ChainCallDelayedExecutor;
/**
* 在前一个任务执行完毕后等待指定时间
* @param delay 等待时间(毫秒)
*/
wait: (delay: number) => ChainCallDelayedExecutor;
/**
* 在等待指定时间后执行前一个任务
* @param delay 等待时间(毫秒)
*/
waitFirst: (delay: number) => ChainCallDelayedExecutor;
/**
* 执行任务队列中的所有任务
*/
execute: () => ChainCallDelayedExecutor;
}
export const main = () => {
/**
* 生成并返回一个 ChainCallDelayedExecutor 对象
* @param name 传入的字符串
*/
const generateExecutor = (name: string): ChainCallDelayedExecutor => {
console.log(`generateExecutor: ${name}`);
// 定义一个名为arrange的函数,接受一个字符串类型的参数name,并返回一个ChainCallDelayedExecutor类型的对象
const tasks: Function[] = [];
const executor: ChainCallDelayedExecutor = {
do: function (callback: Function): ChainCallDelayedExecutor {
tasks.push(callback);
return executor;
},
wait: function (delay: number): ChainCallDelayedExecutor {
tasks.push(() => new Promise((resolve) => setTimeout(resolve, delay)));
return executor;
},
waitFirst: function (delay: number): ChainCallDelayedExecutor {
tasks.unshift(
() => new Promise((resolve) => setTimeout(resolve, delay)),
);
return executor;
},
execute: function (): ChainCallDelayedExecutor {
(async () => {
for (const task of tasks) {
await task();
}
console.log('end', new Date().toLocaleTimeString());
})();
return executor;
},
};
return executor;
};
const executor = generateExecutor('tasks');
console.log('start', new Date().toLocaleTimeString());
executor
.do(() => console.log('first', new Date().toLocaleTimeString()))
.wait(1000)
.do(() => console.log('second', new Date().toLocaleTimeString()))
.waitFirst(1000)
.execute();
};
Taking the inverse of a type
never类型的妙用2【渡一教育】_哔哩哔哩_bilibili
ts
type BanType<T, U> = T extends U ? never : T;
const method = <T>(a: BanType<T, number>) => a;
method('test');
method({});
method(1); // Error: Argument of type '1' is not assignable to parameter of type 'never'.
A task executor that can be paused and resumed
任务队列的中断和恢复【渡一教育】_哔哩哔哩_bilibili
ts
/**
* A task execute process can be paused and resumed.
* @author: Ruan Jiazhen
* @date: 2025-02-04 19:09:34
**/
interface ProcessTasks {
(...arg: Function[]): {
start: () => Promise<any[] | undefined>;
pause: () => void;
};
}
const processTasks: ProcessTasks = function (...arg: Function[]) {
let isRunning = false;
let nextTaskIndex = 0;
const results: any[] = [];
const start = async () => {
if (isRunning) return;
isRunning = true;
while (isRunning && nextTaskIndex < arg.length) {
const task = arg[nextTaskIndex];
const result = await task();
results.push(result);
nextTaskIndex++;
}
if (!isRunning) {
console.log('task paused on index', nextTaskIndex - 1);
return;
}
console.log('all tasks finished');
return results;
};
const pause = () => {
isRunning = false;
};
return {
start,
pause,
};
};
export const main = () => {
const tasks = [
async () => {
console.log('task 1 finished');
return 1;
},
async () => {
await new Promise((resolve) => setTimeout(resolve, 2000));
console.log('task 2 finished');
return 2;
},
async () => {
await new Promise((resolve) => setTimeout(resolve, 3000));
console.log('task 3 finished');
return 3;
},
];
const { start, pause } = processTasks(...tasks);
start().then((res) => {
console.log('1 start res', res);
});
setTimeout(() => {
console.log('try to pause');
pause();
}, 1000);
setTimeout(() => {
console.log('try to resume');
start().then((res) => {
console.log('2 start res', res);
});
}, 3000);
};